package com.jack.atomic;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;

/**
 * @Author jack chan
 * @Description //测试LockSupport
 * @Date 1:35 下午 2020/8/10
 **/
public class LockSupportTest {
    static class MyThread extends Thread{
        @Override
        public void run() {
            synchronized (this){
                System.out.println("before notify");
                notify();
                System.out.println("after notify");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
//        LockSupportTest.WaitAndNotifyDemo();
         LockSupportTest.ParkAndUnParkDemo();
    }

    //wait notify
    private static void WaitAndNotifyDemo(){
        MyThread myThread = new MyThread();

//        myThread.start();
//        Thread.sleep(3000);
        synchronized (myThread){
            try{
                myThread.start(); //虽然这里开启了线程，但是synchronized锁住了类。
                Thread.sleep(3000);
                System.out.println("before wait");
                myThread.wait();
                System.out.println("after wait");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //park unpark
    private static void ParkAndUnParkDemo(){
        LockSupportThread lockSupportThread = new LockSupportThread(Thread.currentThread());
        lockSupportThread.start();
//        //unPark->park start
//        try{
//            Thread.sleep(3000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        //unPark->park end
        /* unPark->park 不会造成waitNotify同步的调用顺序不当引起程序阻塞的情况，所以LockSupport park/unPark 灵活 */
        System.out.println("before park");
        LockSupport.park("ParkAndUnparkDemo"); //开始阻塞线程。等待LockSupport.unpark方法的调用，继续执行下面内容。
        System.out.println("after park");




    }

    static class LockSupportThread extends Thread{
        private Object object;

        public LockSupportThread(Object object){
            this.object = object;
        }

        @Override
        public void run() {
            System.out.println("before unpark");
            try{
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Blocker info " + LockSupport.getBlocker((Thread) object));

            LockSupport.unpark((Thread) object);

            try {
                Thread.sleep(10);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("Blocker info "+ LockSupport.getBlocker((Thread) object));

            System.out.println("after unpark");


        }
    }
}
